package coreservlets.filters;

import java.io.IOException;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class LateAccessFilter implements Filter {
	private static final String START_TIME = "startTime";
	private static final String END_TIME = "endTime";
	
	private FilterConfig config;
	private ServletContext context;
	private int startTime, endTime;
	private DateFormat formatter;

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		GregorianCalendar calendar = new GregorianCalendar();
		int currentTime = calendar.get(Calendar.HOUR_OF_DAY);
		if (isUnusualTime(currentTime, startTime, endTime)) {
			context.log("WARNING: " + req.getRemoteHost() + " accessed "
					+ req.getRequestURL() + " on "
					+ formatter.format(calendar.getTime()));
		}
		chain.doFilter(req, response);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		this.config = config;
		this.context = config.getServletContext();
		this.formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
		try {
			startTime = Integer.parseInt(config.getInitParameter(START_TIME));
			endTime = Integer.parseInt(config.getInitParameter(END_TIME));
		} catch (NumberFormatException e) {
			startTime = 22;
			endTime = 6;
		}
	}

	private boolean isUnusualTime(int currentTime, int startTime, int endTime) {
		// If the start time is less than the end time (i.e.,
		// they are two times on the same day), then the
		// current time is considered unusual if it is
		// between the start and end times.
		if (startTime < endTime) {
			return ((currentTime >= startTime) && (currentTime < endTime));
		}
		// If the start time is greater than or equal to the
		// end time (i.e., the start time is on one day and
		// the end time is on the next day), then the current
		// time is considered unusual if it is NOT between
		// the end and start times.
		else {
			return (!isUnusualTime(currentTime, endTime, startTime));
		}
	}

}
